﻿using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing; // 需要引用 System.Drawing 以使用 Point 类
using System.Windows.Forms;
using System.Threading; // 需要引用 System.Windows.Forms 以使用 Cursor 类

namespace AutoControlSpectrum.Extensions
{
    /// <summary>
    /// window窗体帮助类
    /// </summary>
    public class WindowHelper
    {
        // 导入必要的 Windows API 函数
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll")]
        private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        // 定义 EnumChildWindows 回调函数的委托
        private delegate bool EnumChildProc(IntPtr hWnd, IntPtr lParam);

        // 定义鼠标事件的常量
        private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;

        private const uint MOUSEEVENTF_LEFTUP = 0x0004;
        private const uint WM_CLOSE = 0x0010;

        // RECT 结构体
        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        private string windowTitle;
        private IntPtr hWnd;

        /// <summary>
        /// 构造函数，通过窗口标题找到窗口句柄
        /// </summary>
        /// <param name="windowTitle">窗口标题</param>
        /// <param name="timeoutInSeconds">等待窗口出现的超时时间（秒）</param>
        public WindowHelper(string windowTitle, int timeoutInSeconds = 30)
        {
            this.windowTitle = windowTitle;
            this.hWnd = IntPtr.Zero;

            DateTime startTime = DateTime.Now;

            // 轮询等待窗口出现
            while ((DateTime.Now - startTime).TotalSeconds < timeoutInSeconds)
            {
                this.hWnd = FindWindow(null, windowTitle);
                if (this.hWnd != IntPtr.Zero)
                {
                    break; // 找到窗口，退出循环
                }

                Thread.Sleep(500); // 等待一段时间再重试
            }

            if (this.hWnd == IntPtr.Zero)
            {
                //throw new Exception("目标窗口未找到！");
            }
        }

        /// <summary>
        /// 关闭窗口
        /// </summary>
        public void CloseWindow()
        {
            SendMessage(this.hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
            Console.WriteLine("窗口已关闭！");
        }

        /// <summary>
        /// 点击指定文本的按钮，等待按钮出现
        /// </summary>
        /// <param name="buttonText">按钮文本</param>
        /// <param name="timeoutInSeconds">等待按钮出现的超时时间（秒）</param>
        public void ClickButton(string buttonText, int timeoutInSeconds = 30)
        {
            // 将目标窗口置于前台
            SetForegroundWindow(this.hWnd);

            IntPtr hButton = IntPtr.Zero;
            DateTime startTime = DateTime.Now;

            // 轮询等待按钮出现
            while ((DateTime.Now - startTime).TotalSeconds < timeoutInSeconds)
            {
                hButton = IntPtr.Zero;
                EnumChildWindows(this.hWnd, (hwndChild, lParam) =>
                {
                    StringBuilder sb = new StringBuilder(256);
                    GetWindowText(hwndChild, sb, sb.Capacity);
                    if (sb.ToString() == buttonText)
                    {
                        hButton = hwndChild;
                        return false; // 停止枚举
                    }
                    return true; // 继续枚举
                }, IntPtr.Zero);

                if (hButton != IntPtr.Zero)
                {
                    break; // 找到按钮，退出循环
                }

                Thread.Sleep(500); // 等待一段时间再重试
            }

            if (hButton == IntPtr.Zero)
            {
                return;
                throw new Exception("目标按钮未找到！");
            }

            // 将目标按钮置于前台
            SetForegroundWindow(hButton);

            // 获取按钮的位置
            RECT rect;
            if (!GetWindowRect(hButton, out rect))
            {
                throw new Exception("无法获取按钮位置！");
            }

            int x = rect.Left + (rect.Right - rect.Left) / 2;
            int y = rect.Top + (rect.Bottom - rect.Top) / 2;

            // 移动光标到按钮并点击
            Cursor.Position = new Point(x, y);
            mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, UIntPtr.Zero);
            mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, UIntPtr.Zero);

            Console.WriteLine("按钮已点击！");
        }
    }
}